# 公式编辑页面组件事件初始化
import json
import uuid

from PySide2 import QtWidgets
from PySide2.QtGui import QStandardItemModel, QStandardItem, Qt
from PySide2.QtWidgets import QVBoxLayout, QTableView, QTableWidgetItem, QAbstractItemView, QWidget, QPushButton, \
    QHBoxLayout

import share
from binding import formula_share, conditions_pop
from elementUI.freezeTableWidget import FreezeTableView

# 事件绑定
from util.TableWidgetUtil import TableWidgetUtil
from util.requestUtil import requestUtil

class bind:
    def __init__(self):
        self.ui = share.SI.main.ui
        self.fui = share.SI.formula.ui
        # 设置模板不可修改
        self.ui.formula_tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)

        # 生成公式编辑左侧源表
        mapping_original_tableView = FreezeTableView("mapping_original_tableView",2,5,self.ui.mapping_original_border_widget)
        self.ui.mapping_original_tableView = mapping_original_tableView
        mapping_original_tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        mapping_original_tableView.init()

        # 生成公式编辑左侧源表
        mapping_original_XJ_tableView = FreezeTableView("mapping_original_XJ_tableView",1,1,self.ui.mapping_original_border_widget)
        self.ui.mapping_original_XJ_tableView = mapping_original_XJ_tableView
        mapping_original_XJ_tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        mapping_original_XJ_tableView.init()

        vLayout = QVBoxLayout()
        vLayout.addWidget(mapping_original_tableView)
        vLayout.addWidget(mapping_original_XJ_tableView)
        vLayout.setContentsMargins(5, 2, 5, 2)
        self.ui.mapping_original_border_widget.setLayout(vLayout)
        mapping_original_tableView.show()
        mapping_original_XJ_tableView.show()

        # 编辑公式源表单元格双击事件
        mapping_original_tableView.doubleClicked.connect(lambda: self.table_left_click(mapping_original_tableView))
        mapping_original_tableView.clicked.connect(lambda: self.table_left_OneClick())
        mapping_original_XJ_tableView.doubleClicked.connect(lambda: self.table_left_click(mapping_original_XJ_tableView))
        mapping_original_XJ_tableView.clicked.connect(lambda: self.table_left_OneClick())
        # 公式窗口双击事件
        self.ui.formula_tableWidget.doubleClicked.connect(lambda : self.table_right_click())
        # 返回按钮事件
        self.ui.mapping_back_button.clicked.connect(lambda: self.ui.stackedWidget.setCurrentIndex(4))
        # 添加公式按钮事件
        self.ui.add_button.clicked.connect(lambda: self.add_button_clicked())
        # 确认公式按钮
        self.ui.affirm_button.clicked.connect(lambda :self.affirm_button_clicked())
        # 条件按钮事件
        self.ui.fx_button.clicked.connect(lambda: self.create_condition_fun())
        # 新建条件
        self.fui.create_condition_pushButton.clicked.connect(lambda :self.create_null_condition())
        # 表格点击
        self.fui.formula_tableWidget.clicked.connect(self.formula_tableWidget_fun)
        # 确认条件（组装条件）
        self.fui.affirm_button.clicked.connect(lambda : self.affirm_button_fun())
        # 计算条件事件绑定
        self.formula_group()

    # 单击弹窗置底
    def table_left_OneClick(self):
        if formula_share.flag.flag != 0:
            share.SI.formula.ui.hide()

    def table_right_click(self):

        #         当前选中单元格
        tableWidget = self.ui.formula_tableWidget
        try:
            # 获取当前单元格
            item = tableWidget.selectedItems()[0]
            # 获取单元格所在行列
            rowindex = tableWidget.row(item);
            columnindex = tableWidget.column(item);

            formula = tableWidget.item(rowindex,columnindex).text()

        except:
            pass
        # 将公式添加到公式编辑栏内
        self.ui.formula_compile.setPlainText(formula)


    # 源数据点击事件
    def table_left_click(self,tableView):
        if formula_share.flag.flag != 0:
            share.SI.formula.ui.show()
        try:
            # 查询当前选中单元格行列
            rowIndex = tableView.currentIndex().row();
            columnIndex = tableView.currentIndex().column();

            model = tableView.model()
            # 拼接公式(因为实际的公式表中会新增一列主键，所以这里columnindex增加2)
            if formula_share.flag.zlflag == 0:
                formula = "{" +model.item(rowIndex,0).text() + model.item(rowIndex,1).text()+model.item(rowIndex,2).text()+model.item(rowIndex,3).text()+model.item(rowIndex,4).text() + "," + str(columnIndex+2) + "}"
            else:
                formula = "{" +model.item(rowIndex,0).text() + "," + str(columnIndex+2) + "}"

        except Exception as e:
            print(e)
        # 将公式添加到公式编辑栏内
        self.ui.formula_compile.setPlainText(self.ui.formula_compile.toPlainText()+formula)

        # 如果条件单元格被选中则填入条件单元格
        tableWidgetPO = share.SI.formula.ui.formula_tableWidget
        try:
            # 获取当前单元格
            item = tableWidgetPO.item(formula_share.cell.cellRow, 2)
            if item == None:
                text = ""
            else:
                text = item.text()

            # # 向单元格插入内容
            tableWidgetPO.setItem(formula_share.cell.cellRow, 2, QTableWidgetItem(text+formula))
        except Exception as e :

            pass

    #  添加按钮事件绑定
    def add_button_clicked(self):
        tableWidget = self.ui.formula_tableWidget
        try:
            # 获取当前单元格
            item = tableWidget.selectedItems()[0]
            # # 获取单元格所在行列
            rowindex = tableWidget.row(item);
            columnindex = tableWidget.column(item);
            # 将原有公式的中括号外边去除
            plainText = self.ui.formula_compile.toPlainText().replace("[","").replace("]","")
            # # 向单元格插入内容
            if self.ui.formula_compile.toPlainText() != "":
                tableWidget.setItem(rowindex, columnindex, QTableWidgetItem("[" + plainText + "]"))

            data = [rowindex,columnindex,"[" + plainText + "]"]

            formula_share.dataList.alter_dataList.append(data)

            # 清空公示栏
            self.ui.formula_compile.setPlainText("")
        except:
            pass

    # 新建条件
    def create_condition_fun(self):
        formula_share.flag.flag = 1
        self.fui.formula_tableWidget.setRowCount(0)
        # 判断当前公式是否可回显
        # 获取公式
        formula = self.ui.formula_compile.toPlainText()
        if formula.startswith("[<") and formula.endswith(">]"):
            # 开始处理准备回显
            formula = self.dispose_to_echo(formula)
            # 回显数据
            self.to_echo(formula)

        self.ui.formula_compile.setPlainText("")
        self.fui.show()

    # 处理fx待回显公式
    def dispose_to_echo(self,formula):
        # 判断公式是有多条
        if ">&<" in formula:            #多条
            formula = [item.replace("[","").replace("]","").replace("<","").replace(">","") for item in formula.split(">&<")]
        else:       #单条
            formula.replace("[","").replace("]","").replace("<","").replace(">","")
            formula = [formula]

        return formula

    # 回显fx公式
    def to_echo(self,formula):
        # 渲染公式列表行列
        for index,item in enumerate(formula):
            self.create_null_condition()
            item = item.split(":")
            # 添加数据
            self.fui.formula_tableWidget.setItem(index, 1, QTableWidgetItem(item[0]))
            self.fui.formula_tableWidget.setItem(index, 2, QTableWidgetItem(item[1]))

    # 添加空条件
    def create_null_condition(self):
        rowCount = self.fui.formula_tableWidget.rowCount()
        self.fui.formula_tableWidget.setRowCount(rowCount+1)
        id = str(uuid.uuid1()).replace("-", "")
        self.fui.formula_tableWidget.setItem(rowCount, 0, QTableWidgetItem(id))

        self.fui.formula_tableWidget.setCellWidget(rowCount, 3, self.condition_operation(id))

    # 空条件操作
    def condition_operation(self,id):
        widget=QWidget()

        # 删除
        deleteBtn = QPushButton('删除')
        deleteBtn.setStyleSheet(''' QPushButton{
                                    text-align : center;
                                    background-color : transparent;
                                    height : 30px;
                                    border-style: outset;
                                    border: 1px solid #3550B1;
                                    color: #3550B1;
                                    font : 13px;}
                                    
                                    QPushButton:hover{
                                    	text-decoration:underline;
                                    }''')

        deleteBtn.clicked.connect(lambda : self.del_fun(id))

        hLayout = QHBoxLayout()
        hLayout.addWidget(deleteBtn)
        hLayout.setContentsMargins(5,2,5,2)
        widget.setLayout(hLayout)
        return widget

    # 删除条件
    def del_fun(self,id):
        row = self.fui.formula_tableWidget.findItems(id,Qt.MatchExactly)[0].row()
        # 删除条件
        self.fui.formula_tableWidget.removeRow(row)

    # 记录单元格，弹起编辑框
    def formula_tableWidget_fun(self,index):
        formula_share.cell.cellRow = index.row()
        formula_share.cell.cellColumn = index.column()

        # 查询组织
        dataMap = requestUtil("/organization","GET").dataMap
        share.organization.list = dataMap["data"]

        if index.column() == 1:
            conditions_pop.Example()

    # 确认条件
    def affirm_button_fun(self):
        tableWidget = self.fui.formula_tableWidget
        #     表单行数
        row = tableWidget.rowCount()
        dataText = ""
        for rowIndex in range(row):
            company = tableWidget.item(rowIndex,1).text();
            formula = tableWidget.item(rowIndex,2).text();
            dataText = dataText + "<" + company + ":" + formula + ">&"
        dataText = dataText[:-1]
        # 将拼接好的公式添加到公式框中
        # 清空公示栏
        self.ui.formula_compile.setPlainText(dataText)

    # 公式组按钮绑定
    def formula_group(self):
        self.fui = share.SI.formula.ui
        self.fui.jia_button.clicked.connect(lambda :self.formula_add(self.fui.jia_button))
        self.fui.jian_button.clicked.connect(lambda :self.formula_add(self.fui.jian_button))
        self.fui.cheng_button.clicked.connect(lambda :self.formula_add(self.fui.cheng_button))
        self.fui.chu_button.clicked.connect(lambda :self.formula_add(self.fui.chu_button))
        self.fui.xiaoyu_button.clicked.connect(lambda :self.formula_add(self.fui.xiaoyu_button))
        self.fui.dayu_button.clicked.connect(lambda :self.formula_add(self.fui.dayu_button))
        self.fui.dengyu_button.clicked.connect(lambda :self.formula_add(self.fui.dengyu_button))
        self.fui.budeng_button.clicked.connect(lambda :self.formula_add(self.fui.budeng_button))
        self.fui.and_button.clicked.connect(lambda :self.formula_add(self.fui.and_button))
        self.fui.or_button.clicked.connect(lambda :self.formula_add(self.fui.or_button))
        self.fui.if_button.clicked.connect(lambda :self.formula_add(self.fui.if_button))
        self.fui.else_button.clicked.connect(lambda :self.formula_add(self.fui.else_button))
        self.fui.then_button.clicked.connect(lambda :self.formula_add(self.fui.then_button))

    def formula_add(self,button):
        symbol = button.text()
        # 如果条件单元格被选中则填入条件单元格
        tableWidgetPO = share.SI.formula.ui.formula_tableWidget

        try:
            # 获取当前单元格
            item = tableWidgetPO.item(formula_share.cell.cellRow, 2)
            if item == None:
                text = ""
            else:
                text = item.text()

            # # 向单元格插入内容
            tableWidgetPO.setItem(formula_share.cell.cellRow, 2, QTableWidgetItem(text + " " + symbol + " "))
            share.SI.main.ui.formula_compile.setPlainText(text + " " + symbol + " ")
        except Exception as e :
            QtWidgets.QMessageBox.about(self.ui.formula_tableWidget ,"信息提示框", "请点击公式填写的条件行")

    #   确认按钮事件绑定
    def affirm_button_clicked(self):
        # 拉取模板数据
        tableWidget = self.ui.formula_tableWidget
        rowCount = tableWidget.rowCount()
        clomnCount = tableWidget.columnCount()

        # 被修应该的模板数据
        template_data = []
        for x in range(rowCount):
            row = []
            for y in range(clomnCount):
                # 存在说明备注等情况导致同步失败
                try:
                    row.append(tableWidget.item(x,y).text())
                except:
                    pass
            template_data.append(row)

        # 组装最终数据，由于是JSON所以需要按行组装
        last_data = []
        print(formula_share.dataList.alter_dataList)
        for index in range(len(formula_share.dataList.alter_dataList)):
            row = formula_share.dataList.TData[formula_share.dataList.alter_dataList[index][0]]
            data = json.loads(row['data'])
            data[formula_share.dataList.alter_dataList[index][1]] = formula_share.dataList.alter_dataList[index][2]
            row['data'] = json.dumps(data,ensure_ascii=False)
            last_data.append(row)

        print(last_data)

        dataMap = requestUtil("/mapping","PUT",jsonStr=last_data).dataMap

        try:
            flag = dataMap['flag']
        except:
            QtWidgets.QMessageBox.about(self.ui.formula_tableWidget ,"信息提示框", "请确认已修改公式")
            return

        try:
            QtWidgets.QMessageBox.about(self.ui.formula_tableWidget ,"信息提示框", "提交成功")
        except:
            QtWidgets.QMessageBox.about(self.ui.formula_tableWidget ,"信息提示框", "无权限修改失败")

# 数据绑定
class data_bind:
    def __init__(self,id):
        self.ui = share.SI.main.ui
        # 获取源列表表格
        self.ui.mapping_original_tableView = self.ui.mapping_original_border_widget.findChild(QTableView,"mapping_original_tableView")
        self.ui.mapping_original_XJ_tableView = self.ui.mapping_original_border_widget.findChild(QTableView,"mapping_original_XJ_tableView")
        # 获取原表 体数据
        dataMap = requestUtil("/mapping/findById/" + str(id),"GET").dataMap["data"]
        self.originalList = dataMap["originalList"]
        self.templateList = dataMap["templateList"]
        formula_share.dataList.TData = self.templateList
        # 渲染模板数据
        self.BData_MB()

    # 科目余额表数据绑定
    def BData_KM(self):
        mapping_original_tableView = self.ui.mapping_original_tableView
        # 准备数据
        model = QStandardItemModel()
        # 清空mapping_original_tableView表格
        mapping_original_tableView.set_model(model)
        # 处理model(赋值)
        self.get_original_data(model)
        mapping_original_tableView.set_model(model)
        # 合并表头
        self.merge_header()

    # 现金流量表数据绑定
    def BData_XJ(self):
        mapping_original_XJ_tableView = self.ui.mapping_original_XJ_tableView
        # 准备数据
        model = QStandardItemModel()
        # 清空mapping_original_tableView表格
        mapping_original_XJ_tableView.set_model(model)
        # 处理model(赋值)
        self.get_original_data(model)
        mapping_original_XJ_tableView.set_model(model)

    # 查询源数据体
    def get_original_data(self,model):

        dataList = [row["data"] for index,row in enumerate(self.originalList)]

        for index,item in enumerate(dataList):
            item = json.loads(item, strict=False)
            for col,itemcol in enumerate(item):
                model.setItem(index, col, QStandardItem(itemcol))
                # 将可转换为数字的文字转为数字
                if  col != 0 and self.is_number(itemcol.replace(",","")):
                    model.item(index, col).setTextAlignment(Qt.AlignRight|Qt.AlignVCenter)

    # 为模板表格绑定数据
    def BData_MB(self):
        formula_tableWidget = self.ui.formula_tableWidget
        formula_tableWidget.horizontalHeader().setVisible(True)
        # 将json串转换为对象
        dataList = [json.loads(row["data"], strict=False) for index,row in enumerate(self.templateList)]
        TableWidgetUtil().head_color_show(formula_tableWidget,v=False,q=False,r=False)
        formula_tableWidget.setRowCount(0)

        # 列表中最长的列
        lenMax = 0
        for index,item in enumerate(dataList):
            if lenMax < len(item):
                lenMax = len(item)

        # 设置表头
        head_data = [" "] * len(dataList[0])
        formula_tableWidget.setRowCount(len(dataList))
        formula_tableWidget.setColumnCount(lenMax)
        formula_tableWidget.setHorizontalHeaderLabels(head_data)
        # 渲染主体数据
        for rowindex,row in enumerate(dataList):
            for colindex,col in enumerate(row):
                formula_tableWidget.setItem(rowindex, colindex, QTableWidgetItem(str(col)))
                # if formula_tableWidget.item(rowindex, colindex) != None:
                    # 内容居中
                formula_tableWidget.item(rowindex, colindex).setTextAlignment(Qt.AlignHCenter|Qt.AlignVCenter)

    # 判断字符串是否是数字
    def is_number(self,target_str):
        try:
            float(target_str)
            return True
        except:
            pass
        if target_str.isnumeric():
            return True
        return False

    # 合并表头
    def merge_header(self):
        # 合并表头
        mapping_original_tableView = self.ui.mapping_original_border_widget.findChild(QTableView,"mapping_original_tableView")

        # 获取表头列数
        original_model = mapping_original_tableView.horizontalView.model()
        columnCount = original_model.columnCount()
        # 有效单元格记录（每出现一个新的头记录一次）
        valid_cell_data = -1
        valid_cell_index = -1
        # 纵向合并记录
        vertical_merger = False
        # 遍历获取合并区间
        for column in range(columnCount):
            # 表头文字居中
            mapping_original_tableView.horizontalView.model().item(0, column).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter);
            mapping_original_tableView.horizontalView.model().item(1, column).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter);


            indexOne = original_model.index(0, column)      #第一行索引
            indexTwo = original_model.index(1, column)      #第二行索引
            dataOne = str(original_model.data(indexOne))       #第一行值
            dataTwo = str(original_model.data(indexTwo))       #第二行值
            if (dataOne != valid_cell_data and dataOne != ""):          # 该单元格内容有效

                # 若有效记录不为-1则记录上次合并
                if valid_cell_index != -1:
                    if vertical_merger:         #合并包含第二列
                        mapping_original_tableView.horizontalView.setSpan(0,valid_cell_index,2,column-valid_cell_index)
                        mapping_original_tableView.BRTableView.setSpan(0,valid_cell_index,2,column-valid_cell_index)
                    else:                       #合并不包含第二列
                        mapping_original_tableView.horizontalView.setSpan(0,valid_cell_index,1,column-valid_cell_index)
                        mapping_original_tableView.BRTableView.setSpan(0,valid_cell_index,1,column-valid_cell_index)
                    vertical_merger = False

                if dataTwo == dataOne or dataTwo == "":         #该次合并包含第二列
                    vertical_merger = True

                valid_cell_index = column
                valid_cell_data = dataOne

        # 进行最后一次合并
        if vertical_merger:         #合并包含第二列
            mapping_original_tableView.horizontalView.setSpan(0,valid_cell_index,2,columnCount-valid_cell_index)
            mapping_original_tableView.BRTableView.setSpan(0,valid_cell_index,2,columnCount-valid_cell_index)
        else:                       #合并不包含第二列
            mapping_original_tableView.horizontalView.setSpan(0,valid_cell_index,1,columnCount-valid_cell_index)
            mapping_original_tableView.BRTableView.setSpan(0,valid_cell_index,1,columnCount-valid_cell_index)